<?php

/**
 * 七贝云仓-武安保税仓 SDK
 * @author chenyun
 */

namespace App\Service\VendorClient\Shopwuan;
use App\Service\Code\Normal;
use Service\AppService\IdService;
use App\Service\HttpServer\Http;
use App\Model\PssLogModel\MicroServiceLog;
class ShopwuanApiClient
{
    private $account  = 'Shopwuan';
    protected $config;
    
    /**
     * 初始参数
     * @param obj $collection
     */
    public function __construct( $apiBody = [] ) 
    {
        $this->config = $apiBody;
    }
    
    /**
     * 创建订单
     */
    public function createOrder( $params = [] ) 
    {   
        ini_set('serialize_precision', 16);
        
        if( empty($params['supplierOrder']) || empty($params['orderGoods']) || empty($params['order']) || empty($params['binfo']) ) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder or orderGoods or order or binfo");
        }
        //组装订单参数
        $orderInfo = $params['supplierOrder'];
        $order     = $params['order'];
        $binfo     = $params['binfo'];

        //运费
        $deliver_money  = $orderInfo['deliver_money'];
        //商品下单组
        $OrderList = $productAmt ='';
        foreach ($params['orderGoods'] as $key => $item ) 
        { 
            //卖价
            $price              = $item['price'];
            //商品购买规格数量
            $spec_num           = $item['spec_num'];
            //商品购买数量(下单数量 X 起售数量)
            $quantity           = $item['quantity'];
            //实际购买数量
            $buyAcount          = $spec_num * $quantity ;
            //单个商品价格
            $singleGoodsPrice   = bcdiv((string)$price, (string)$spec_num,3);
            $singleGoodsPrice   = ceil(bcmul((string)$singleGoodsPrice,(string)'100',1));
            $singleGoodsPrice   = bcdiv((string)$singleGoodsPrice,'100',2);

            //单个商品含税价格
            $totalGoods     = bcmul((string)$singleGoodsPrice,(string)$buyAcount,2);
            //商品组
            $OrderList .= $this->arrToXml(['ceb:OrderList'=>
                $this->arrToXml([
                'ceb:gnum'      => $key+1,
                'ceb:itemNo'    => $item['supplier_skucode'],
                'ceb:itemName'  => $item['goods_name'],
                'ceb:unit'      => 'PCS',
                'ceb:qty'       => $buyAcount,
                'ceb:price'     => $singleGoodsPrice
                ])
            ]);
            $productAmt = bcadd((string)$productAmt,(string)$totalGoods,2);
        }
        //实际下单金额
        $real_total_money = $orderInfo['real_total_money'];
        //订单金额 = 商品金额+运费
        $ActualPaidAmt = bcadd((string)$productAmt,$deliver_money,2);
        //优惠金额
        $discount_money = bcsub((string)$ActualPaidAmt,$real_total_money,2);
        //下单支付的时候支付信息
        $apply_extends  = @json_decode($orderInfo['apply_extends'],true);
        //支付时间
        $payTime        = empty($order['payTime']) ? $orderInfo['pay_time'] :$order['payTime'];
        //支付时间
        $pay_time       = $payTime ? $payTime : time();
        $pay_time       = date('Y-m-d H:i:s',$pay_time);
        
        
        //支付流水号
        $pay_sn         = $order['paySerial']??$orderInfo['pay_sn'];
        
        //电商平台信息
        $enterpriseNum = $apply_extends['enterpriseNum'] ?? ''; 
        $enterpriseName = $apply_extends['enterpriseName'] ?? '';
        $enterpriseNum = $order['enterpriseNum'] ? $order['enterpriseNum'] : $enterpriseNum;
        $enterpriseName = $order['enterpriseName'] ? $order['enterpriseName'] : $enterpriseName;
        
        //支付公司信息 
        $payCommanyCode = $apply_extends['payCommanyCode'] ?? '';
        $payCommanyName = $apply_extends['payCommanyName'] ?? '';
        $payCommanyCode = $order['payCommanyCode'] ? $order['payCommanyCode'] : $payCommanyCode;
        $payCommanyName = $order['payCommanyName'] ? $order['payCommanyName'] : $payCommanyName;
         
        $guid = $this->randstrpay();
        $OrderHead= [
            'ceb:guid'              => $guid,
            'ceb:appType'           =>  "1",
            'ceb:appTime'           => date("YmdHis",time()),
            'ceb:appStatus'         => "2", 
            'ceb:orderType'         => "I1210",
            'ceb:orderNo'           => $orderInfo['supplier_dsn'],
            'ceb:ebpCode'           => $enterpriseNum,
            'ceb:ebpName'           => $enterpriseName,
            'ceb:ebcCode'           => $this->config["ebcCode"],
            'ceb:ebcName'           => $this->config["ebcName"], 
            'ceb:goodsValue'        => $productAmt,
            'ceb:freight'           => $deliver_money,
            'ceb:discount'          => $discount_money,
            'ceb:taxTotal'          => "0.00",
            'ceb:acturalPaid'       => $real_total_money,
            'ceb:currency'          => "142",
            'ceb:buyerRegNo'        => $orderInfo["buyer_phone"],
            'ceb:buyerName'         => $orderInfo["buyer_realname"],
            'ceb:buyerTelephone'    => $orderInfo["buyer_phone"],
            'ceb:buyerIdType'       => "1",
            'ceb:buyerIdNumber'     => $orderInfo["buyer_idcard"],
            'ceb:payCode'           => $payCommanyCode,
            'ceb:payName'           => $payCommanyName,
            'ceb:payTransactionId'  => $pay_sn,
            'ceb:consignee'         => $orderInfo['receive_name'],
            'ceb:consigneeTelephone'=> $orderInfo['recveive_phone'],
            'ceb:consigneeProvince' => $orderInfo['province'],
            'ceb:consigneeCity'     => $orderInfo['city'],
            'ceb:consigneeCounty'   => $orderInfo['district'],
            'ceb:consigneeAddress'  => $orderInfo['receive_address'],
            'ceb:note'              => $orderInfo["order_remark"],
        ];
        $OrderHead      = $this->arrToXml(['ceb:OrderHead'=>$this->arrToXml($OrderHead)]);
        $Order          = $this->arrToXml([
            'ceb:Order'   => $OrderHead.$OrderList
        ]);
        $data = '<?xml version="1.0" encoding="UTF-8"?>
            <ceb:CEB311Message guid="'.$guid.'" version="1.0"  xmlns:ceb="http://www.chinaport.gov.cn/ceb" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                '.$Order.'</ceb:CEB311Message>';
        $requestParam = [
            'method'    => 'createOrder',
            'data'      => $data
        ];
        $res = $this->execute($requestParam);
        return $res;
    }
   
    /**
     * 获取取消订单
     */
    public function cancelOrder( $params = [] ) 
    {
        return Normal::returnCode(Normal::SUC,"处理完成");
    }
    
    /**
     * 组装xml
     */
    public function arrToXml(  $params = [] )
    {
        $xml = '';
        foreach ($params as $key=>$val){
            $xml .= "<{$key}>{$val}</{$key}>
            ";
        }
        return $xml;
    }

    /**
     * 随机36位字符串
     */
    function randstrpay($length=36) {
        $rand='';
        $randstr= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $max = strlen($randstr)-1;
        mt_srand((double)microtime()*1000000);
        for($i=0;$i<$length;$i++) {
            $rand.=$randstr[mt_rand(0,$max)];
        }
        return strtoupper($rand);
    }
  /**
     * 加签
     * @param array $param
     */
    protected function getSign ($param)
    {

        $ase_key =substr(openssl_digest(openssl_digest($this->config["ase_key"], 'sha1', true), 'sha1', true), 0, 16);
        $iv = '';
        $res =openssl_encrypt($param,'AES-128-ECB', $ase_key,OPENSSL_RAW_DATA,$iv);
        return base64_encode($res);
    }
    
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute( $param = [] )  
    {
        if( empty($param['data']) ) {
            return Normal::returnCode(Normal::FAIL,"数据不能为空");
        }
        $method  = $param["method"];
        $data   = $this->getSign($param["data"]);
        $url     = $this->config["baseurl"];
        $start_time     = microtime(true);
        $res            = Http::postTextPlainCurl($url,$data);
        $httpCode       = Http::getHttpCode();
        MicroServiceLog::instance()->addLog([
            'interface_code'    => $this->account.'_'.$method,
            'request_url'       => $url,
            'request_param'     => $data,
            'response_code'     => $httpCode,
            'response_data'     => $res,
            'start_time'        => $start_time,
        ]);
        $resHttp = json_decode($res);
        $resHttp = json_encode($resHttp,JSON_UNESCAPED_UNICODE);
        $resHttp = json_decode($resHttp,true);
        if( isset($resHttp['success']) && $resHttp['success'] == true) {
            return Normal::returnCode(Normal::SUC,"操作成功",$resHttp);
        }
        $message = isset($resHttp['msg']) ? $resHttp['msg'] : '请求失败';
        return Normal::returnCode(Normal::FAIL,$message);
    }
}